<template>
  <scroll class="listview"
          :data="data"
          ref="listview"
          :listenScroll="listenScroll"
          :probeType="probeType"
          @scroll="scroll"
  >
    <ul>
      <li v-for="(group,index) in data" class="list-group" ref="listGroup">
         <h2 class="list-group-title">{{group.title}}</h2>
        <ul>
          <li v-for="(item,index) in group.items" class="list-group-item" @click="selectItem(item)">
            <img v-lazy="item.avatar" alt="" class="avatar">
            <span class="name">{{item.name}}</span>
          </li>
        </ul>
      </li>
    </ul>
    <!--阻止事件冒泡和浏览器原生滚动-->
    <div class="list-shortcut" @touchstart.stop.prevent="onShortcutTouchStart" @touchmove.stop.prevent="onShortcutTouchMove">
      <ul>
        <!--:data-index 扩展属性-->
        <li v-for="(item,index) in shortcutList"
            class="item"
            :data-index="index"
            :class="{'current': currentIndex === index}"
        >
          {{item}}
        </li>
      </ul>
    </div>
    <div class="list-fixed" v-show="fiexdTitle" ref="fixed">
      <h1 class="fixed-title">{{fiexdTitle}}</h1>
    </div>
    <div class="loading-container" v-show="!data.length">
      <loading></loading>
    </div>
  </scroll>
</template>

<script>
  import Scroll from 'base/scroll/scroll'
  import Loading from 'base/loading/loading'
  import {getData} from "common/js/dom";
  // 字体高度+pandding值
   const ANCHOR_HEIGHT = 18;
   // 吸顶title高度
   const TITLE_HEIGHT = 30;
  export default {
        name: "listview",
      created() {
        //  创建对象
        //  data 会被vue添加set get 做监听
        //  我们不需要监听它的变化 只需要共享
        this.touch = {};
        this.listenScroll = true;
        this.listHeight = [];
        this.probeType = 3;
      },
      data() {
          return {
            scrollY: -1, // 实时监听滚动事件
            currentIndex: 0, // 显示高亮
            diff: -1 //计算吸顶栏上限与下限差值
          }
      },
      props: {
          data: {
            type: Array,
            default: []
          }
      },
      computed: {
          // 获取右侧的快速列表标题
        shortcutList() {
          // 得到title的集合数组
          return this.data.map((group) => {
            return group.title.substring(0,1)
          })
        },
        fiexdTitle() {
          // scrollY>0 设置为空
          if (this.scrollY > 0) {
            return ''
          }
          return this.data[this.currentIndex] ? this.data[this.currentIndex].title : '';
        }
      },
      components: {
        Scroll,
        Loading
      },
      methods: {
        selectItem(item) {
          this.$emit('select',item)
        },
        onShortcutTouchStart(e) {
          let anchorIndex = getData(e.target,'index');
          // 手指触碰到的第一个位置
          let fristTouch = e.touches[0];
          this.touch.y1 = fristTouch.pageY;
          // 记录点击当前点击锚点的索引
          this.touch.anchorIndex = anchorIndex;
          this._scrollTo(anchorIndex);
        },
        onShortcutTouchMove(e) {
          // 从start到move计算两者差
          let fristTouch = e.touches[0];
          this.touch.y2 = fristTouch.pageY;
          // 获取Y轴的偏移锚点
          // | 0 向下取整
          let delta = (this.touch.y2 - this.touch.y1) / ANCHOR_HEIGHT | 0
          // 得到move的时候的anchorIndex
          let anchorIndex = parseInt(this.touch.anchorIndex) + delta;

          this._scrollTo(anchorIndex);
        },
        scroll(pos) {
          // 获取BSY轴滚动的距离
          this.scrollY = pos.y;
        },
        _scrollTo(index) {
          // 解决当点击时 无法对应字体高亮
          // 点击上下边界为空
          if(!index && index!==0) {
            return
          }
          // 滑动上下边界index为负 或者 index大于最大长度
          if (index <0) {
            index = 0;
          } else if (index > this.listHeight.length -2) {
            index = this.listHeight.length -2;
          }
          // 点击获取它上限位置 即可高亮
          this.scrollY = -this.listHeight[index];
          console.log(this.currentIndex)
          //最后0代表动画效果 0为立即触发
          this.$refs.listview.scrollToElement(this.$refs.listGroup[index],0)
        },
        //计算高度
        _calculateHeight() {
          this.listHeight = [];
          const list = this.$refs.listGroup;
          let height = 0;
          this.listHeight.push(height);
          // 循环遍历每个group的高度
          for (let i =0; i <list.length; i++) {
            // 得到每一个group元素
            let item = list[i];
            height += item.clientHeight;
            // 得到每个group对应的高度
            this.listHeight.push(height)
          }
        }
      },
      watch: {
          data() {
            // 数据重新渲染后重新计算高度
            setTimeout(() => {
              this._calculateHeight()
            },20)
          },
        // 观测scrollY的变化
        scrollY(newY) {
          // newY Y轴偏移点 == pos.y
          const listHeight = this.listHeight;
          // 当滚动到顶部 newY大于0
          if (newY > 0) {
            this.currentIndex = 0;
            return
          }
          // 在中间部分滚动
          // 旧下限 == 新上限故 减一
          for (let i =0; i < listHeight.length -1; i++) {
            // 得到上限
            let height1 = listHeight[i];
            // 得到下限
            let height2 = listHeight[i+1];
            // 假如落在最底部 或者在上限和下限之间 currentIndex就等于当前的位置
            // 往上滚动Y轴为负值 -newY为正直
            if (-newY >= height1 && -newY < height2) {
              this.currentIndex = i;
              // 得到上限与滚动的值
              this.diff = height2 + newY;
              return
            }
          }
          // 滚动到底部且-newY大于最后一个元素的上限
          this.currentIndex = listHeight - 2;
        },
        diff(newVal) {
            let fixedTop = (newVal > 0 && newVal < TITLE_HEIGHT) ? newVal - TITLE_HEIGHT : 0;
            // this.fixedTop where ar you from ?
            if (this.fixedTop === fixedTop) {
              return
            }
            // console.log(this.fixedTop)
            this.fixedTop = fixedTop;
            // translate3d 开启gpu加速
            this.$refs.fixed.style.transform = `translate3d(0,${fixedTop}px,0)`
        }
      }
    }
</script>

<style scoped lang="stylus" rel="stylesheet/stylus">
  @import "~common/stylus/variable"

  .listview
    position: relative
    width: 100%
    height: 100%
    overflow: hidden
    background: $color-background
    .list-group
      padding-bottom: 30px
      .list-group-title
        height: 30px
        line-height: 30px
        padding-left: 20px
        font-size: $font-size-small
        color: $color-text-l
        background: $color-highlight-background
      .list-group-item
        display: flex
        align-items: center
        padding: 20px 0 0 30px
        .avatar
          width: 50px
          height: 50px
          border-radius: 50%
        .name
          margin-left: 20px
          color: $color-text-l
          font-size: $font-size-medium
    .list-shortcut
      position: absolute
      z-index: 30
      right: 0
      top: 50%
      transform: translateY(-50%)
      width: 20px
      padding: 20px 0
      border-radius: 10px
      text-align: center
      background: $color-background-d
      font-family: Helvetica
      .item
        padding: 3px
        line-height: 1
        color: $color-text-l
        font-size: $font-size-small
        &.current
          color: $color-theme
    .list-fixed
      position: absolute
      top: 0
      left: 0
      width: 100%
      .fixed-title
        height: 30px
        line-height: 30px
        padding-left: 20px
        font-size: $font-size-small
        color: $color-text-l
        background: $color-highlight-background
    .loading-container
      position: absolute
      width: 100%
      top: 50%
      transform: translateY(-50%)
</style>
